package com.sakura.demo.gateway.utils;

import com.alibaba.fastjson.JSONObject;
import com.sakura.demo.common.error.ErrorType;
import com.sakura.demo.common.model.JsonResponseEntity;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.core.io.buffer.DataBufferUtils;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.nio.charset.StandardCharsets;


/**
 * @Author: zhengcan
 * @Date: 2022/5/10
 * @Description:
 * @Version: 1.0.0 创建
 */
public class WebfluxResponseUtil {

    /**
     * 封装异常信息时的response
     * @param exchange
     * @param errorType 异常类型
     * @return
     */
    public static Mono<Void> responseFailed(ServerWebExchange exchange, ErrorType errorType) {
        return responseFailed(exchange, HttpStatus.INTERNAL_SERVER_ERROR.value(), errorType);
    }

    /**
     * 封装异常信息时的response
     * @param exchange
     * @param httpStatus http的响应状态
     * @param errorType 异常类型
     * @return
     */
    public static Mono<Void> responseFailed(ServerWebExchange exchange, int httpStatus, ErrorType errorType) {
        JsonResponseEntity entity = new JsonResponseEntity(errorType.getMessage(), errorType.getCode());
        return responseWrite(exchange, httpStatus, entity);
    }

    /**
     * 封装异常信息时的response
     * @param exchange
     * @param httpStatus http的响应状态
     * @param errorMsg 异常信息
     * @return
     */
    public static Mono<Void> responseFailed(ServerWebExchange exchange, int httpStatus, String errorMsg) {
        JsonResponseEntity entity = new JsonResponseEntity(errorMsg, httpStatus);
        return responseWrite(exchange, httpStatus, entity);
    }

    /**
     * 构建response
     * @param exchange
     * @param httpStatus HTTP状态
     * @param result
     * @return
     */
    public static Mono<Void> responseWrite(ServerWebExchange exchange, int httpStatus, JsonResponseEntity result) {
        DataBuffer buffer = getDataBuffer(exchange, httpStatus, JSONObject.toJSONString(result));
        return exchange.getResponse().writeWith(Mono.just(buffer)).doOnError((error) -> DataBufferUtils.release(buffer));
    }

    /**
     * 构建DataBuffer
     * @param exchange
     * @param httpStatus HTTP状态
     * @param responseBody 响应体
     * @return
     */
    private static DataBuffer getDataBuffer(ServerWebExchange exchange, int httpStatus, String responseBody) {
        if (httpStatus == 0) {
            httpStatus = HttpStatus.INTERNAL_SERVER_ERROR.value();
        }
        ServerHttpResponse response = exchange.getResponse();
        response.getHeaders().setAccessControlAllowCredentials(true);
        response.getHeaders().setAccessControlAllowOrigin("*");
        response.setStatusCode(HttpStatus.valueOf(httpStatus));
        response.getHeaders().setContentType(MediaType.APPLICATION_JSON_UTF8);
        response.getHeaders().setContentLength(responseBody.getBytes(StandardCharsets.UTF_8).length);
        return response.bufferFactory().wrap(responseBody.getBytes(StandardCharsets.UTF_8));
    }

    /**
     * 将对象转成DataBuffer
     * @param exchange
     * @param errorType 异常类型
     * @param httpStatus HTTP状态
     * @return
     */
    public static DataBuffer transfromObjectToDataBuffer(ServerWebExchange exchange, int httpStatus, ErrorType errorType) {
        JsonResponseEntity entity = new JsonResponseEntity(errorType.getMessage(), errorType.getCode());
        return getDataBuffer(exchange, httpStatus, JSONObject.toJSONString(entity));
    }

}
